/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

/**
 *
 * @author cheeven.tsai
 */
public class AWSAPICall {

    SignedRequestsHelper helper = null;
    SAXBuilder parser = null;

    public AWSAPICall() {
        try {
            parser = new SAXBuilder();
            helper = new SignedRequestsHelper();
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) throws Exception {

        HashMap<String, String> params = new HashMap<String, String>();
        params.put("Service", "AWSECommerceService");
        params.put("Operation", "BrowseNodeLookup");
        params.put("Version", "2011-08-11");
        params.put("BrowseNodeId", "1000");
        params.put("AWSAccessKeyId", "AKIAJMSSTEDH23JSOXFQ");

        AWSAPICall apiCall = new AWSAPICall();

        Document doc = apiCall.getResponseDOM(params);

        XMLOutputter outputter = new XMLOutputter();
        outputter.output(doc, System.out);

    }

    public InputStream getResponseInputStream(HashMap<String, String> params) {
        try {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.INFO, params.toString());
            URL url = new URL(helper.sign(params));
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.INFO, url.toString());
            
            URLConnection conn = url.openConnection();
            InputStream in = conn.getInputStream();
            return in;
        } catch (MalformedURLException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public Document getResponseDOM(HashMap<String, String> params) {
        try {
            InputStream in = this.getResponseInputStream(params);
            if (in != null) {
                return parser.build(in);
            }
        } catch (JDOMException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public void getResponseInFile(HashMap<String, String> params, String fileName) {
        PrintWriter out = null;
        try {
            InputStream in = this.getResponseInputStream(params);
            if (in == null) {
                return;
            }
            File file = new File(fileName);
            out = new PrintWriter(new FileWriter(file));
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = reader.readLine();
            while (line != null) {
                out.println(line);
                line = reader.readLine();
            }
            reader.close();
            out.flush();
            out.close();
        } catch (IOException ex) {
            Logger.getLogger(AWSAPICall.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            out.close();
        }

    }
}
